package com.hll.erp.controller;

import com.hll.erp.entity.ResultMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.ShiroException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA @Author yuanhaoyue swithaoy@gmail.com @Description 异常处理 @Date
 * 2018-04-09 @Time 17:09
 */
@RestControllerAdvice
@Slf4j
public class ExceptionController {
  private final ResultMap resultMap;

  @Autowired
  public ExceptionController(ResultMap resultMap) {
    this.resultMap = resultMap;
  }

  // 捕捉shiro的异常
  @ExceptionHandler(ShiroException.class)
  public ResultMap handleShiroException() {
    return resultMap.fail().code(401).message("您没有权限访问！");
  }

  @ExceptionHandler(NullPointerException.class)
  public ResultMap handleNullPointException() {
    return resultMap.fail().code(301).message("参数可能没给全");
  }

  // 捕捉其他所有异常
  @ExceptionHandler(Exception.class)
  public ResultMap globalException(HttpServletRequest request, Throwable ex) {
    return resultMap
        .fail()
        .code(getStatus(request).value())
        .message("访问出错，无法访问: " + ex.getMessage());
  }

  private HttpStatus getStatus(HttpServletRequest request) {
    Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
    if (statusCode == null) {
      return HttpStatus.INTERNAL_SERVER_ERROR;
    }
    return HttpStatus.valueOf(statusCode);
  }

  /**
   * 处理参数校验异常
   *
   * @param e
   * @return
   */
  @ExceptionHandler(MethodArgumentNotValidException.class)
  public ResultMap handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {

    String message =
        e.getBindingResult().getAllErrors().stream()
            .map(DefaultMessageSourceResolvable::getDefaultMessage)
            .collect(Collectors.joining());
    log.error("校验参数异常 message:{} exception:{}", message, e.getMessage(), e);
    return new ResultMap().fail().code(403).message(message);
  }
}
